#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <cmath>

using namespace std;

struct Item {
    int id;
    int value;
    int weight;
    double value_density;
};

struct Node {
    int level;
    int value;
    int weight;
    double bound;
};

// 计算上界时使用贪心法（按价值密度排序）
double calculateBound(const Node &node, const vector<Item> &items, int capacity) {
    if (node.weight >= capacity) return 0;

    // 创建剩余物品的副本并按价值密度排序
    vector<Item> remaining_items;
    for (int i = node.level + 1; i < items.size(); i++) {
        remaining_items.push_back(items[i]);
    }
    sort(remaining_items.begin(), remaining_items.end(), 
         [](const Item &a, const Item &b) { return a.value_density > b.value_density; });

    double bound = node.value;
    int remaining_capacity = capacity - node.weight;
    int i = 0;

    // 贪心装入剩余物品
    while (i < remaining_items.size() && remaining_capacity >= remaining_items[i].weight) {
        bound += remaining_items[i].value;
        remaining_capacity -= remaining_items[i].weight;
        i++;
    }

    // 分数背包
    if (i < remaining_items.size() && remaining_items[i].value_density > 0) {
        bound += remaining_capacity * remaining_items[i].value_density;
    }

    return bound;
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        cerr << "Usage: " << argv[0] << " <filepath>" << endl;
        return 1;
    }
    
    string filepath = argv[1];

    int n, capacity;
    cin >> n >> capacity;

    if(n > 500){
        cout << filepath << "," << -2 << endl;
        return 0;
    }
    
    vector<Item> items(n);
    for (int i = 0; i < n; ++i) {
        double value_double, weight_double;
        cin >> value_double >> weight_double;
        
        int value = static_cast<int>(round(value_double));
        int weight = static_cast<int>(round(weight_double));
        double value_density = (weight > 0) ? static_cast<double>(value) / weight : 0.0;
        
        items[i] = {i + 1, value, weight, value_density};
    }

    // 不排序，保持原始顺序

    auto cmp = [](const Node &a, const Node &b) { return a.bound < b.bound; };
    priority_queue<Node, vector<Node>, decltype(cmp)> pq(cmp);

    Node root = {-1, 0, 0, 0};
    root.bound = calculateBound(root, items, capacity);
    pq.push(root);

    int max_value = 0;
    while (!pq.empty()) {
        Node current = pq.top();
        pq.pop();

        if (current.bound < max_value) continue;

        if (current.level >= n - 1) {
            if (current.value > max_value) {
                max_value = current.value;
            }
            continue;
        }

        int next_level = current.level + 1;
        
        // 选择当前物品
        if (next_level < items.size()) {
            Node left = {
                next_level,
                current.value + items[next_level].value,
                current.weight + items[next_level].weight,
                0
            };
            left.bound = calculateBound(left, items, capacity);

            if (left.weight <= capacity && left.bound >= max_value) {
                pq.push(left);
                if (left.value > max_value) {
                    max_value = left.value;
                }
            }
        }

        // 不选择当前物品
        Node right = {
            next_level,
            current.value,
            current.weight,
            0
        };
        right.bound = calculateBound(right, items, capacity);

        if (right.bound >= max_value) {
            pq.push(right);
        }
    }

    cout << filepath << "," << max_value << endl;

    return 0;
} 